/**
 * 防抖
 * @param {funtion}
 * @param {number}
 * @return {undefined}
 */
export function debounce(fn, delay = 200, _this) {
  // var delay = delay || 200
  let timer = null
  return function (...args: any[]) {
    const self = _this || this
    // const args = arguments
    timer && clearTimeout(timer)
    timer = setTimeout(function () {
      timer = null
      fn.apply(self, args)
    }, delay)
  }
}
/**
 * 节流
 * @param {funtion}
 * @param {number}
 * @param {boolean} 是否间隔时间之后再执行
 * @return {undefined}
 */
export function throttle(fn, delay = 200, path = false) {
  let last
  let timer
  return function (...args: any[]) {
    const self = this
    // const args = arguments
    const now = +new Date()
    if (last && now - last < delay) {
      if (path) {
        clearTimeout(timer)
        timer = setTimeout(function () {
          last = now
          fn.apply(self, args)
        }, delay)
      }
    } else {
      last = now
      fn.apply(self, args)
    }
  }
}
/**
 * 判断类型
 * @param {any}
 * @return {string}
 */
export function typeOf(argu) {
  const map = {
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Boolean]': 'boolean',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Array]': 'array',
    '[object Arguments]': 'arguments',
    '[object Function]': 'function',
    '[object Error]': 'error',
    '[object Date]': 'date',
    '[object RegExp]': 'regexp',
    '[object Object]': 'object'
  }
  const str = Object.prototype.toString.call(argu)
  return map[str]
}
/**
 * 生成uuid
 * @return {string}
 */
export function Uuid() {
  const s = []
  const hexDigits = '0123456789abcdef'
  for (let i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
  }
  s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = '-'

  const uuid = s.join('')
  return uuid
}

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0 || !time) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (typeof time === 'string') {
      if (/^[0-9]+$/.test(time)) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if (typeof time === 'number' && time.toString().length === 10) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}
/**
 * Parse the time to string
 * @returns {string}
 */
export function getRandom() {
  const length = Math.round(Math.random() * 18) + 32
  let res = ''
  for (let i = 0; i < length - 1; i++) {
    res = res + Math.floor(Math.random() * 10)
  }
  return res
}
/**
 * Parse the time to string
 * @returns {string}
 */
export function downLoad(url: string) {
  const link = document.createElement('a')
  link.href = url
  link.download = ''
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}
/**
 * Parse the time to string
 * @returns number | string | array | object | null | undefined | boolean
 * @returns Boolean
 */
export function valuable(o: any) {
  const type = typeOf(o)
  if (type === 'string' && o) {
    return true
  }
  if (type === 'number') {
    return true
  }
  if (type === 'array' && o.length) {
    return true
  }
  if (type === 'boolean') {
    return true
  }
  if (type === 'object' && Object.keys(o).length) {
    return true
  }
  return false
}

/**
 * excel导入插件方法：excel时间格式化
 * @param d excel时间格式
 * @param cFormat 转换分隔符
 * @returns 标准时间格式
 */
export function formatExcelDate(d, cFormat) {
  if (typeOf(d) == 'number') {
    const date = new Date((d - 1) * 24 * 3600000 + 1)
    date.setYear(date.getFullYear() - 70)
    return parseTime(date, cFormat)
  } else if (typeOf(d) == 'string') {
    const time = new Date(d)
    return parseTime(time, cFormat)
  } else {
    return d
  }
}

export function numberToChinese(num) {
  const chineseNums = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
  const chineseUnits = ['', '十', '百', '千']

  if (num === 0) {
    return chineseNums[0]
  }

  let chineseStr = ''
  let unitIndex = 0

  while (num > 0) {
    const digit = num % 10
    if (digit !== 0) {
      // 处理非零数字
      chineseStr = chineseNums[digit] + chineseUnits[unitIndex] + chineseStr
    } else {
      // 处理连续的零，只在个位数为零时添加零
      if (chineseStr.length > 0 && chineseStr.charAt(0) !== chineseNums[0]) {
        chineseStr = chineseNums[0] + chineseStr
      }
    }

    num = Math.floor(num / 10)
    unitIndex++
  }

  return chineseStr
}

export function timeFilter(t) {
  const n = new Date()
  const d = parseTime(n, '{y}-{m}-{d}')
  const y = parseTime(n, '{y}')

  if (t.includes(d)) {
    return parseTime(t, '{h}:{i}')
  } else if (t.includes(y)) {
    return parseTime(t, '{m}-{d} {h}:{i}')
  } else {
    return parseTime(t, '{y}-{m}-{d} {h}:{i}')
  }
}

export function setUrlParams(obj) {
  const urlParams = new URLSearchParams(window.location.search)
  const url = window.location.href.includes('?')
    ? window.location.href.split('?')[0]
    : window.location.href

  // 添加新的参数或更新已有参数
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      urlParams.set(key, obj[key])
    }
  }
  // 将更新后的 URL 参数应用到浏览器历史记录
  window.history.pushState({}, '', `${url}?${urlParams}`)
}
